using System;
using System.Collections.Generic;
using Microsoft.Practices.ObjectBuilder2;
using Guard=Common.Core.Guard;

namespace Common.Unity.Extensions.PropertyMapper
{
	public class PropertyExpressionMapping
	{
		readonly string firstExpression, secondExpression;
		readonly Type typeConverterType;

		public PropertyExpressionMapping( string firstExpression, string secondExpression ) : this( firstExpression, secondExpression, null )
		{}

		public PropertyExpressionMapping( string firstExpression, string secondExpression, Type typeConverterType )
		{
			Guard.IsNotNullOrEmpty( firstExpression, "firstExpression" );
			Guard.IsNotNullOrEmpty( secondExpression, "firstExpression" );
			this.firstExpression = firstExpression;
			this.secondExpression = secondExpression;
			this.typeConverterType = typeConverterType;
		}

		public string FirstExpression
		{
			get { return firstExpression; }
		}

		public string SecondExpression
		{
			get { return secondExpression; }
		}

		public Type TypeConverterType
		{
			get { return typeConverterType; }
		}

		public virtual IPropertySetterInfo CreateProperty( PropertyMappingContext context )
		{
			LinkedList<PropertyMappingExpressionContext> 
				sourceContext = PropertyMappingExpressionContextResolver.Eval( context.Source, FirstExpression ),
				targetContext = PropertyMappingExpressionContextResolver.Eval( context.Target, SecondExpression );
			return
				new PropertyMappingExpressionPropertySetterInfo( sourceContext.Last.Value, targetContext.Last.Value,
				                                                 TypeConverterType );
		}

		public virtual PropertyExpressionMapping CreateMirror()
		{
			return new PropertyExpressionMapping( SecondExpression, FirstExpression, TypeConverterType );
		}
	}
}